#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "userload.h"
#include <unistd.h>

extern char *return_user_mask(char[]) ;
extern char *return_oper_mask(struct Client *) ;
extern int str2array(char **pparv, char *string, char *delim) ;
extern char *crypt ();

#define MAXVIRTSIZE     (3 + 5 + 1)

void calc_mask(aClient *acptr) 
{
#ifdef CLIENT_MASKING

#ifdef OPER_MASKS
  if (IsNetAdmin(acptr) || 
      IsNetManager(acptr) ||
      IsNetFounder(acptr) ||
      IsSRoot(acptr) ||
      IsSAdmin(acptr) ||
      IsAdmin(acptr) ||
      IsOper(acptr) ||
      IsLocOp(acptr)) {
    strncpy(acptr->user->mask, return_oper_mask(acptr), HOSTLEN + 1) ;
    return ;
  }
#endif

  strncpy(acptr->user->mask, return_user_mask(acptr->user->host), HOSTLEN +1) ;
  printf("check: %s \n",return_user_mask(acptr->user->host) );  
#endif /* CLIENT_MASKING */   
}

char *return_host(struct Client *caller, struct Client *user) 
{
#ifdef CLIENT_MASKING
  /* hiding a user's host from it's self is stupid and leads to bugs */
  if (!IsHidden(user) || IsOper(caller) || caller==user)  
    return user->user->host ;
  else 
    return user->user->mask ;
#else
  return user->user->host ;
#endif        
}

char *return_oper_host(struct Client *caller, struct Client *user)
{
#ifdef CLIENT_MASKING
# ifdef OPER_MASKS
  if (!IsNetAdmin(caller) &&
      !IsNetManager(caller) &&
      !IsNetFounder(caller) &&
      !IsSRoot(caller) &&
      !IsSAdmin(caller) &&
      !IsAdmin(caller) &&
      !IsOper(caller) &&
      !IsLocOp(caller) && 
      MaskHost(user) && 
      caller!=user)
    return user->user->mask  ;
  else
    return user->user->host ;    
# else
  if (!IsHidden(user) || IsOper(caller) || caller==user)
    return user->user->host ;
  else
    return user->user->mask ;
# endif
#else
  return user->user->host ;
#endif
}

#ifdef OPER_MASKS

char *return_oper_mask(struct Client *acptr)
{
    if (IsHidden(acptr)) {
	if (IsNetAdmin(acptr))
	    return netadmin_host;
	else if (IsNetManager(acptr))
	    return netmanager_host;
	else if (IsNetFounder(acptr))
	    return netfounder_host;
	else if (IsSRoot(acptr))
	    return sroot_host;
	else if (IsSAdmin(acptr))
	    return sadmin_host;
	else if (IsAdmin(acptr))
	    return admin_host;
	else if (IsOper(acptr))
	    return ircop_host;
	else if (IsLocOp(acptr))
	    return locop_host;
    } else {
	return acptr->user->host;
    }
};
#endif

#ifdef CLIENT_MASKING

char *Maskchecksum(char *data, char *salt)
{
  char static tmp[HOSTLEN + 1] ;
  char result[HOSTLEN +1] ;  
  
  strncpy(tmp,crypt(data, salt),HOSTLEN) ;
  printf("%s/n",tmp) ;           
  return (tmp) ;
}


char *return_user_mask(char *s)
{
    static char mask[HOSTLEN + 1];
    char *csum;
    char *dot, *ptr ;
    static char destroy[HOSTLEN + 1], *parv[HOSTLEN + 1];
    char salt[12] = "$1$\0\0\0\0\0\0\0\0\0";
    int len = 0, overflow = 0, parc = 0;
    
    strncpy(destroy, s, HOSTLEN);
    len = strlen(destroy);

    if ((len + MAXVIRTSIZE) > HOSTLEN) {
        overflow = (len + MAXVIRTSIZE) - HOSTLEN;
        ptr = &destroy[overflow];
    } else {
        ptr = &destroy[0];
    }
    memset(mask, 0, HOSTLEN);
    
    parc = str2array(parv, ptr, ".");

    if (strlen(s) > HOSTLEN) {
        s[HOSTLEN] = 0;
    }
    
    if (parc == 4) {
        len = strlen(parv[3]);
        if (isdigit(parv[3][len - 1])) {
            /* Numeric IP, lets use the last octets of the IP address
             * as salt */
            strcat(salt, parv[3]);
            strcat(salt, parv[2]);
            csum = Maskchecksum(s, salt);
            sprintf(mask, "%s.%s.%s.%i", parv[0], parv[1],parv[2],csum[15]+256+csum[19]);
            return mask;
        }
    }

    /* Hostname.... lets use it as our salt... */
    strncat(salt, s, 8);
    csum = Maskchecksum(s, salt);

    dot = (char *) strchr(s, '.');
    
    if (dot == NULL) {
        sprintf(mask, userspace_mask_prefix "%i%i%i%i%i%i.%s",csum[14]%10,csum[15]%10,csum[16]%10,csum[17]%10,csum[18]%10,csum[19]%10, s);
        return mask;
    } else {
        sprintf(mask, userspace_mask_prefix "%i%i%i%i%i%i.%s",csum[14]%10,csum[15]%10,csum[16]%10,csum[17]%10,csum[18]%10,csum[19]%10, dot + 1);
        return mask;
    }
}

#endif /* CLIENT_MASKING */

int str2array(char **pparv, char *string, char *delim)
{
    char *tok;
    int pparc = 0;

    tok = (char *)strtok(string, delim);
    while (tok != NULL) {
        pparv[pparc++] = tok;
        tok = (char *)strtok(NULL, delim);
    }

    return pparc;
}
